package com.gerfmarquez.nymph.music.core;

import java.util.ArrayList;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.SystemClock;
import android.util.Log;

import com.gerfmarquez.nymph.ui.threads.UpdatePlayStateNotesThread;

public class PlayNotesThread extends Thread {
	
	 int noteType;
	 static final String TAG= "PlayNotesThread";
	 static byte[][] NOTES;
	 static byte[] rhythms;
	 UpdatePlayStateNotesThread uPSN;
	 
   	 
     int minBuffSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
     AudioTrack audioTrack = new AudioTrack( AudioManager.STREAM_MUSIC,  44100,
    		 AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_8BIT,
 			minBuffSize, AudioTrack.MODE_STREAM);
//   	 This constructor will probably be removed because it's not needed.
//   	 public PlayNotesThread(int noteType, ArrayList<AudioTrack> audioTracks, byte[][] notesToPlay) {
//		    audioTrack = new AudioTrack( AudioManager.STREAM_MUSIC,  44100,
//		    		AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_8BIT,
//					minBuffSize, AudioTrack.MODE_STREAM);
//		 audioTracks.add(audioTrack);
//   		 android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
//   		 this.noteType = noteType;
//   		NOTES = notesToPlay;
//   		 Log.d(TAG, "Min Buffer size is "+minBuffSize);
//		}
   	 public PlayNotesThread(byte[] rhythmsToPlay, ArrayList<AudioTrack> audioTracks, byte[][] notesToPlay, UpdatePlayStateNotesThread uPSN) {
   		 this.uPSN = uPSN;
   		 audioTrack = new AudioTrack( AudioManager.STREAM_MUSIC,  44100,
   				AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_8BIT,
   				 minBuffSize, AudioTrack.MODE_STREAM);
   		 audioTracks.add(audioTrack);
   		 android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
   		 NOTES = notesToPlay;
   		 Log.d(TAG, "Min Buffer size is "+minBuffSize);
   		rhythms = rhythmsToPlay; 
   	 }
   	
   	public void run() {
   		
   		byte[]  audByte;
   		int noteRhythm = noteType;
   		int songArrayIndex = 0;
//   		int compass = 3;
//   		int numberOfCompasses = 3;
   		
   		int bytesToWriteWithBPMinTotal = 0;
   		int totalBytes;
   		int bytesPerNote[] = new int[rhythms.length+1];
   		bytesPerNote[0] = 0;
//   		if(rhythms == null) {
//   			bytesToWriteWithBPMinTotal = MusicCore.cutLength(noteRhythm);
//   			totalBytes = bytesToWriteWithBPMinTotal*NOTES.length; 
//   		}
//   		else {
		for(int i= 1; i<rhythms.length+1;i++) {
			int bytesOnThisNote = MusicCore.cutLength(rhythms[i-1]);
			bytesToWriteWithBPMinTotal += bytesOnThisNote;
			bytesPerNote[i] = bytesOnThisNote+bytesPerNote[i-1];
			
			Log.d(TAG,"Rhythm :"+i+" length "+rhythms[i-1]);
		}
		uPSN.setBytesPerNote(bytesPerNote);
		totalBytes = bytesToWriteWithBPMinTotal;
//   		}
   		AudioTrack aud = audioTrack;
   		byte []songArray = null;
   		Log.d(TAG, "Total songArrayBytes = " + totalBytes);
   		songArray = new byte[totalBytes];
   		for (int i = 0; i< NOTES.length; i++) {
   			int rhythm = 0;
   			if(rhythms != null) {
   				rhythm = rhythms[i];
   			}
   			else {
   				rhythm = noteType;
   			}
   			int bytesToWriteWithBPMperNote = MusicCore.cutLength(rhythm);
   			audByte =  NOTES[i];
   		
   			Log.d(TAG, "Note number: "+i+" ");
   				
				songArray = MusicCore.append(songArray, audByte, songArrayIndex,bytesToWriteWithBPMperNote);
				songArrayIndex += bytesToWriteWithBPMperNote;
				
   			Log.d(TAG, "Bytes to write with bpm : " +bytesToWriteWithBPMperNote);
   		}
   		
   		Log.d(TAG, "play back state is: " +aud.getPlayState());
   		aud.play();
   		Log.d(TAG, "play back state is: " +aud.getPlayState());
   		
   		int currentTempBuffIndex =  0;
   		while(currentTempBuffIndex < songArray.length) {
				byte[] tempBuff = new byte[minBuffSize];
				int i = 0;
				minBufferLoop:
				for(; i<minBuffSize; i++,currentTempBuffIndex++) {
					if(currentTempBuffIndex >= songArray.length) {
						break minBufferLoop;
					}
					tempBuff[i] = songArray[currentTempBuffIndex];
					uPSN.changeToPlayState(currentTempBuffIndex);
				}
   			aud.write(tempBuff, 0, i);
   			Log.d(TAG, "Thread id" +this.getId());
   		}
   		Log.d(TAG, "play back state is: " +aud.getPlayState());
   	}
}
